﻿package com.zhuangyzh.cmpp;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class CMPPContainer {
    private static Socket msgSocket;
    private static DataInputStream in;
    private static DataOutputStream out;

    public static DataInputStream getSocketDIS() {
        if (in == null || null == msgSocket || msgSocket.isClosed()) {
            try {
                in = new DataInputStream(CMPPContainer.getSocketInstance()
                        .getInputStream());
            } catch (IOException e) {
                in = null;
            }
        }
        return in;
    }

    public static DataOutputStream getSocketDOS() {
        if (out == null || null == msgSocket || msgSocket.isClosed()) {
            try {
                out = new DataOutputStream(CMPPContainer.getSocketInstance()
                        .getOutputStream());
            } catch (IOException e) {
                out = null;
            }
        }
        return out;
    }

    public static Socket getSocketInstance() {
        if (null == msgSocket || msgSocket.isClosed()) {
            try {
                in = null;
                out = null;
                msgSocket = new Socket();
                int timeouts = 5000;
                SocketAddress socketAddress = new InetSocketAddress(
                        CMPPManager.getServerIp(), CMPPManager.getServerPort());
                try {
                    msgSocket.connect(socketAddress, timeouts);
                } catch (SocketTimeoutException e) {
                    e.printStackTrace();
                    System.out.println("connet to server timeout " + timeouts);
                    return null;
                }
                // msgSocket.setKeepAlive(true);
                in = getSocketDIS();
                out = getSocketDOS();
            } catch (UnknownHostException e) {
                System.out.println("Socket链接短信网关端口号不正确：" + e.getMessage());
                // 链接短信网关
            } catch (IOException e) {
                System.out.println("Socket链接短信网关失败：" + e.getMessage());
            }
        }
        return msgSocket;
    }

    /**
     * 关闭socket和相关IO
     * 
     * @throws IOException
     */
    public static void ReleaseSocketInstance() {
        if (null == msgSocket) {
            try {
                in.close();
                in = null;
                out.close();
                out = null;
                msgSocket.close();
                msgSocket = null;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }

    /**
     * 创建Socket链接后请求链接ISMG
     * 
     * @return
     */
    public static int connectISMG() {
        CMPPConnnect connect = new CMPPConnnect();
        connect.setTotal_Length(12 + 6 + 16 + 1 + 4);// 消息总长度，级总字节数:4+4+4(消息头)+6+16+1+4(消息主体)
        connect.setCommand_Id(CMPPDefine.CMPP_CONNECT);// 标识创建连接
        connect.setSequence_Id(CMPPDefine.getSequence());// 序列，由我们指定
        connect.setSourceAddr(CMPPManager.getCompanyCode());// 我们的企业代码
        connect.setAuthenticatorSource(CMPPDefine.getAuthenticatorSource(
                CMPPManager.getCompanyCode(), CMPPManager.getPwd()));// md5(企业代码+密匙+时间戳)
        connect.setTimestamp(Integer.parseInt(CMPPDefine.getTimestamp()));// 时间戳(MMDDHHMMSS)
        connect.setVersion((byte) CMPPDefine.CMPP_VERSION);// 版本号 高4bit为3，低4位为0
        List<byte[]> dataList = new ArrayList<byte[]>();
        dataList.add(connect.toByteArry());
        CMPPSender sender = new CMPPSender(getSocketDOS(), getSocketDIS(), dataList);
        try {
            return sender.start();
        } catch (Exception e) {
            try {
                out.close();
            } catch (IOException e1) {
                out = null;
            }
            return -1;
        }
    }

    /**
     * 发送短短信
     * 
     * @return
     */
    public static int sendShortMsg(String msg, String number) {
        try {
            int seq = CMPPDefine.getSequence();
            CMPPSubmit submit = new CMPPSubmit();
            submit.setTotal_Length(12 + 8 + 1 + 1 + 1 + 1 + 10 + 1 + 32 + 1 + 1
                    + 1 + 1 + 6 + 2 + 6 + 17 + 17 + 21 + 1 + 32 + 1 + 1
                    + msg.length() * 2 + 20);
            submit.setCommand_Id(CMPPDefine.CMPP_SUBMIT);
            submit.setSequence_Id(seq);
            submit.setPkTotal((byte) 0x01);
            submit.setPkNumber((byte) 0x01);
            submit.setRegisteredDelivery((byte) 0x00);
            submit.setMsgLevel((byte) 0x01);
            submit.setFeeUserType((byte) 0x02);
            submit.setFeeTerminalId("");
            submit.setFeeTerminalType((byte) 0x00);
            submit.setTpPId((byte) 0x00);
            submit.setTpUdhi((byte) 0x00);
            submit.setMsgFmt((byte) 0x0F);
            submit.setMsgSrc(CMPPManager.getCompanyCode());
            submit.setSrcId(CMPPManager.getServiceCode());
            submit.setDestTerminalId(number);
            submit.setMsgLength((byte) (msg.length() * 2));
            submit.setMsgContent(msg.getBytes("gb2312"));
            submit.setServiceId(CMPPManager.getBusinessCode());

            List<byte[]> dataList = new ArrayList<byte[]>();
            dataList.add(submit.toByteArry());
            CMPPSender sender = new CMPPSender(getSocketDOS(), getSocketDIS(), dataList);
            System.out.println("向手机号码："+number+"下发短短信，序号为:"+seq);
            return sender.start();
        } catch (Exception e) {
            try {
                out.close();
            } catch (IOException e1) {
                out = null;
            }
            System.out.println("发送短短信" + e.getMessage());
            return -1;
        }
    }

    /**
     * 发送长短信
     * 
     * @return
     */
    @SuppressWarnings("unused")
    private static boolean sendLongMsg(String msg, String cusMsisdn) {
        try {
            byte[] allByte = msg.getBytes("UTF-16BE");
            List<byte[]> dataList = new ArrayList<byte[]>();
            int msgLength = allByte.length;
            int maxLength = 140;
            int msgSendCount = msgLength % (maxLength - 6) == 0 ? msgLength
                    / (maxLength - 6) : msgLength / (maxLength - 6) + 1;
            // 短信息内容头拼接
            byte[] msgHead = new byte[6];
            msgHead[0] = 0x05;
            msgHead[1] = 0x00;
            msgHead[2] = 0x03;
            msgHead[3] = (byte) CMPPDefine.getSequence();
            msgHead[4] = (byte) msgSendCount;
            msgHead[5] = 0x01;
            int seqId = CMPPDefine.getSequence();
            for (int i = 0; i < msgSendCount; i++) {
                // msgHead[3]=(byte)MsgUtils.getSequence();
                msgHead[5] = (byte) (i + 1);
                byte[] needMsg = null;
                // 消息头+消息内容拆分
                if (i != msgSendCount - 1) {
                    int start = (maxLength - 6) * i;
                    int end = (maxLength - 6) * (i + 1);
                    needMsg = CMPPDefine.getMsgBytes(allByte, start, end);
                } else {
                    int start = (maxLength - 6) * i;
                    int end = allByte.length;
                    needMsg = CMPPDefine.getMsgBytes(allByte, start, end);
                }
                int subLength = needMsg.length + msgHead.length;
                byte[] sendMsg = new byte[needMsg.length + msgHead.length];
                System.arraycopy(msgHead, 0, sendMsg, 0, 6);
                System.arraycopy(needMsg, 0, sendMsg, 6, needMsg.length);
                CMPPSubmit submit = new CMPPSubmit();
                submit.setTotal_Length(12 + 8 + 1 + 1 + 1 + 1 + 10 + 1 + 32 + 1
                        + 1 + 1 + 1 + 6 + 2 + 6 + 17 + 17 + 21 + 1 + 32 + 1 + 1
                        + subLength + 20);
                submit.setCommand_Id(CMPPDefine.CMPP_SUBMIT);
                submit.setSequence_Id(seqId);
                submit.setPkTotal((byte) msgSendCount);
                submit.setPkNumber((byte) (i + 1));
                submit.setRegisteredDelivery((byte) 0x00);
                submit.setMsgLevel((byte) 0x01);
                submit.setFeeUserType((byte) 0x00);
                submit.setFeeTerminalId("");
                submit.setFeeTerminalType((byte) 0x00);
                submit.setTpPId((byte) 0x00);
                submit.setTpUdhi((byte) 0x01);
                submit.setMsgFmt((byte) 0x08);
                submit.setMsgSrc(CMPPManager.getCompanyCode());
                submit.setSrcId(CMPPManager.getServiceCode());
                submit.setDestTerminalId(cusMsisdn);
                submit.setMsgLength((byte) subLength);
                submit.setMsgContent(sendMsg);
                dataList.add(submit.toByteArry());
            }
            CMPPSender sender = new CMPPSender(getSocketDOS(), getSocketDIS(),
                    dataList);
            sender.start();
            System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                    .format(new Date())
                    + "向"
                    + cusMsisdn
                    + "下发长短信，序列号为:"
                    + seqId);
            return true;
        } catch (Exception e) {
            try {
                out.close();
            } catch (IOException e1) {
                out = null;
            }
            System.out.print("发送长短信" + e.getMessage());
            return false;
        }
    }

    public static int sendActiveTest() {
        CMPPActiveTest active = new CMPPActiveTest();
        active.setTotal_Length(12);// 消息总长度，级总字节数:4+4+4(消息头)+6+16+1+4(消息主体)
        active.setCommand_Id(CMPPDefine.CMPP_ACTIVE_TEST);// 标识创建连接
        active.setSequence_Id(CMPPDefine.getSequence());// 序列，由我们指定
        List<byte[]> dataList = new ArrayList<byte[]>();
        dataList.add(active.toByteArry());
        CMPPSender sender = new CMPPSender(getSocketDOS(), getSocketDIS(), dataList);
        System.out.println("发送 CMPP_ACTIVE_TEST 序号：" + active.getSeqid());
       
        try {
            return sender.start();
        } catch (Exception e) {
            try {
                out.close();
            } catch (IOException e1) {
                out = null;
            }
            return -1;
        }

    }

    public static int sendActiveTestResp(CMPPActiveTestResp activeresp) {
        activeresp.setTotal_Length(12 + 1);
        activeresp.setCommand_Id(CMPPDefine.CMPP_ACTIVE_TEST_RESP);// 标识创建连接
        // activeresp.setSequence_Id(CMPPDefine.getSequence());//序列，由我们指定
        activeresp.setReserved((byte) 0x00);
        List<byte[]> dataList = new ArrayList<byte[]>();
        dataList.add(activeresp.toByteArry());
        CMPPSender sender = new CMPPSender(getSocketDOS(), getSocketDIS(),
                dataList);
        try {
            return sender.start();
        } catch (Exception e) {
            try {
                out.close();
            } catch (IOException e1) {
                out = null;
            }
            return -1;
        }
    }

    public static void dealwithISMG() {
        while (true) {
            try {
                Thread.sleep(15000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sendActiveTest();

        }

    }

}
